package typejump;

import java.awt.BorderLayout;

import javax.swing.JFrame;

import typejump.engine.GameEngine;
import typejump.engine.OnGoingThing;
import typejump.gui.Canvas;
import typejump.gui.CommandWidget;
import typejump.gui.EditorPanel;
import typejump.gui.SwagWidget;
import typejump.objects.Actor;
import typejump.objects.Item;
import typejump.objects.MessageBox;
import typejump.objects.Player;
import typejump.objects.Surface;
import typejump.objects.SwagDropItem;

/**
 * This is the main class which keeps track
 * of some variables and starts everything off.
 * @author g
 *
 */
public class TypeJump {

	private JFrame frame;
	private Canvas canvas;
	private PlayerCommands commands;
	private CommandWidget commandWidget;
	
	private EditorPanel editor;
	
	private Swagger swagMeter = Swagger.getInst();
	
	// Global Variables
	public static int SCREEN_WIDTH = 640;
	public static int SCREEN_HEIGHT = 480;
	
	public static double SWAG_REGEN_RATE = Settings.getDouble("swag.regen"); // swag per second
	
	private int mouseGridSnapAmount = 10;
	private boolean mouseGridSnap = true;
	
	private volatile boolean editing = false;
	
	public static void main(String[] args) {
		for (String s : args)
			System.out.println("> " + s);
		getInst();

		
		GameEngine.start();
		getInst().canvas.start();
	}
	
	private static TypeJump me;
	public static synchronized TypeJump getInst() {
		if (me == null) me = new TypeJump();
		return me;
	}
	
	private TypeJump() {
		frame = new JFrame("Type Jump");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		editor = new EditorPanel();
		
		canvas = new Canvas();
		frame.add(canvas);
		
		commands = new PlayerCommands(this);
		canvas.addKeyListener(commands);
		canvas.addMouseListener(commands);
		
		createWidgets();
		
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		showEditor();
		
		// Test Level

		
//		Player player = GameEngine.getPlayer();
//		player.left(200);
//		player.top(0);
//		player.width(Settings.getDouble("player.width"));
//		player.height(Settings.getDouble("player.height"));
//		
//		Surface floor = new Surface(10, 400, 500);
//		GameEngine.addObject(floor);
//		int y = 360;
//		for (int i = 0; i < 10; i++) {
//			Surface s = new Surface(400 + i * 60, y, 100);
//			s.setAutoScale(false);
//			s.loopAnimation("brick block");
//			GameEngine.addObject(s);
//			if (i % 3 == 0) y -= 70;
//			else if (i % 2 == 0) y -= 60;
//			else y -= 40;
//		}
//		
//		y = 300;
//		for (int i = 0; i <= 5; i++) {
//			Surface s = new Surface(260, y, 100);
//			s.loopAnimation("brick");
//			s.scaleToImage();
//			y -= s.ih();
//			GameEngine.addObject(s);
//		}
//		
//		GameEngine.addObject(new Surface(-103, 400, 100));
//		GameEngine.addObject(new Surface(-203, 400, 100));
//		
//		Item swagDrop = new SwagDropItem();
//		swagDrop.centerX(300);
//		swagDrop.centerY(-200);
//		GameEngine.addObject(swagDrop);
		
		//GameEngine.addCommand("dev infinite swag");
		GameEngine.addCommand("dev pf");
		GameEngine.addCommand("dev dak");
		GameEngine.addCommand("dev load level foo");
		GameEngine.addCommand("dev ep");
		

		GameEngine.addOnGoingThing(new OnGoingThing() {

			@Override
			public boolean happen(TypeJump tj, double seconds) {
				Actor player = GameEngine.getPlayer();
				if (player != null)
					player.vx(Settings.getDouble("go.base"));
				return false;
			}
			
		});
		
		new Thread() { public void run() { try { Thread.sleep(1000); } catch (Exception e) {}
		MessageBox mb = new MessageBox();
		mb.setMessage("Hello, World!\nThis is my test message.\nIsn't it neat?");
		mb.width(150);
		mb.height(50);
		mb.centerX(150);
		mb.centerY(200);
		GameEngine.addEffect(mb);
		}}.start();
	}
	
	public boolean isShowingEditor() {
		return editing;
	}
	
	public void showEditor() {
		editing = true;
		GameEngine.addCommand("dev ep");
		GameEngine.setFocusOnPlayer(false);
		frame.remove(editor);
		frame.add(editor, BorderLayout.EAST);
		frame.pack();
	}
	
	public void hideEditor() {
		editing = false;
		GameEngine.setFocusOnPlayer(true);
		frame.remove(editor);
		frame.pack();
	}
	
	public void setGridSnapAmount(int am) {
		this.mouseGridSnapAmount = am;
	}
	
	public void enableGridSnap() {
		mouseGridSnap = true;
	}
	public void disableGridSnap() {
		mouseGridSnap = false;
	}
	public boolean toggleGridSnap() {
		return mouseGridSnap = !mouseGridSnap;
	}
	
	public double getSnappy(double d) {
		if (mouseGridSnap)
			return mouseGridSnapAmount * (int)(d / mouseGridSnapAmount);
		return d;
	}
	
	public double getMouseX() {
		if (mouseGridSnap)
			return mouseGridSnapAmount * ((int)canvas.getPointerX() / mouseGridSnapAmount);
		return canvas.getPointerX();
	}
	
	public double getMouseY() {
		if (mouseGridSnap)
			return mouseGridSnapAmount * ((int)canvas.getPointerY() / mouseGridSnapAmount);
		return canvas.getPointerY();
	}
	
	public boolean isKeyDown(int code) {
		return commands.isKeyDown(code);
	}
	
	public Swagger getSwagMeter() {
		return swagMeter;
	}
	
	public void setDisplayedCommand(String text) {
		commandWidget.setCommand(text);
	}
	
	private void createWidgets() {
		commandWidget = new CommandWidget();
		SwagWidget swagWidget = new SwagWidget(swagMeter);
		canvas.addWidget(commandWidget);
		canvas.addWidget(swagWidget);
	}
	
	public Player getPlayer() {
		return GameEngine.getPlayer();
	}
}
